﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using ClassLibrary;
using ObTookit.HighLight;
using ObTookit.Init;
using ObTookit.Model;

namespace ObTookit
{
    public partial class MainForm : Form
    {
        #region 字段属性
        string dbcs = "";
        string dbName = "";
        AutoObject auto = null;
        Dictionary<string, string> SQLSentenceDict = new Dictionary<string, string>();
        Dictionary<string, string> SQLTableDict = new Dictionary<string, string>();
        List<CodeFileObject> cfos = null;
        CodeFileObject cfo = null;
        #endregion

        public MainForm()
        {
            InitializeComponent();
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            //this.Font = new System.Drawing.Font("微软雅黑", 9);
            //获取数据库连接串
            //获取数据库，表，字段语句
            //（增加重新加载上面信息的按钮）
            //选择数据库
            //选择表
            //读取命名空间相关的配置项
            //根据数据库名和表名，初始化AutoObject对象
            GetMsSqlDBCS();
            if (!GetMsSqlDatabase())
            {
                this.Dispose();
            }

            this.tab_main_content.TabPages.Remove(this.tpg_permit); //隐藏掉权限tabpage

            tab_main_content.SelectedIndexChanged += tab_main_content_SelectedIndexChanged;
            rtbx_info.TextChanged += rtbx_info_TextChanged;
            //
            cfos = new List<CodeFileObject>();
        }

        void rtbx_info_TextChanged(object sender, EventArgs e)
        {
            CsHighLight cshl = new CsHighLight();
            cshl.SetWords();
            cshl.SetWordsColor(rtbx_info);
        }

        void tab_main_content_SelectedIndexChanged(object sender, EventArgs e)
        {
            CsHighLight cshl = new CsHighLight();
            cshl.SetWords();

            switch (tab_main_content.SelectedIndex)
            {
                case 0: //Info
                    MessageBox.Show("重新加载中......");
                    //cshl.SetWordsColor(rtbx_info); //去掉，否则会造成卡死
                    break;
                case 1: //Qry
                    cshl.SetWordsColor(rtbx_qry);
                    break;
                case 2: //Permit
                    //cshl.SetWordsColor(rtbx_permit);
                    break;
                case 3: //DA
                    cshl.SetWordsColor(rtbx_da);
                    break;
                case 4: //LG
                    cshl.SetWordsColor(rtbx_lg);
                    break;
                case 5: //Serv
                    cshl.SetWordsColor(rtbx_serv);
                    break;
                case 6: //Api
                    cshl.SetWordsColor(rtbx_api);
                    break;
                case 7: //Aspx
                    HtmlHighLight ahl = new HtmlHighLight();
                    ahl.SetWordsColor(rtbx_aspx, rtbx_aspx.Text);
                    break;
                case 8: //Js
                    JsHighLight jhl = new JsHighLight();
                    jhl.SetWordsColor(rtbx_js, rtbx_js.Text);
                    break;
                case 9: //Ctrl
                    cshl.SetWordsColor(rtbx_ctrl);
                    break;
                case 10:    //View
                    HtmlHighLight vhl = new HtmlHighLight();
                    vhl.SetWordsColor(rtbx_view, rtbx_view.Text);
                    break;
                case 11:    //SQL
                    SqlHighLight shl = new SqlHighLight();
                    shl.SetWordsColor(rtbx_sql, rtbx_sql.Text);
                    break;
                case 12:    //Doc
                    DocHighLight dhl = new DocHighLight();
                    dhl.SetWordsColor(rtbx_doc, rtbx_doc.Text);
                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// 数据库下拉列表
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmb_main_dblist_SelectedIndexChanged(object sender, EventArgs e)
        {
            dbName = this.cmb_main_dblist.SelectedValue.ToString();
            if (!string.IsNullOrWhiteSpace(dbName) &&
                dbName != "System.Data.DataRowView")
            {
                GetMsSqlTable(dbName);
            }
        }
        /// <summary>
        /// 右键菜单
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cntMenu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            RichTextBox rtb = (sender as ContextMenuStrip).SourceControl as RichTextBox;
            rtb.Focus();

            if (e.ClickedItem.Text.Equals("SelectAll", StringComparison.CurrentCultureIgnoreCase))
            {
                rtb.SelectAll();
                tss_lbl_rtbx_menu.Text = "已全选";
            }
            if (e.ClickedItem.Text.Equals("Copy", StringComparison.CurrentCultureIgnoreCase))
            {
                Clipboard.SetData(DataFormats.UnicodeText, rtb.SelectedText);
                tss_lbl_rtbx_menu.Text = "已复制";
            }
            //Console.WriteLine(e.ClickedItem.Text);

            //e.ClickedItem.Text
        }

        #region 显示生成的代码（RichTextBox设置文本）
        private void ClearRichTextBox()
        {
            rtbx_info.Clear();
            rtbx_api.Clear();
            rtbx_aspx.Clear();
            rtbx_ctrl.Clear();
            rtbx_da.Clear();
            rtbx_doc.Clear();
            rtbx_js.Clear();
            rtbx_lg.Clear();
            //rtbx_permit.Clear();
            rtbx_qry.Clear();
            rtbx_serv.Clear();
            rtbx_sql.Clear();
            rtbx_view.Clear();
        }
        private void SetRichTextBox(DataTable dt)
        {
            ClearRichTextBox();
            AutoCoder acoder = new AutoCoder(auto, dt);

            if (cfos.Count > 0)
            {
                cfos.Clear();
            }

            rtbx_info.Text = acoder.CreateInfo();
            cfo = new CodeFileObject();
            cfo.FileName = auto.ClsName + "Info";
            cfo.FileExt = ".cs";
            cfo.Content = rtbx_info.Text;
            cfos.Add(cfo);

            rtbx_api.Text = acoder.CreateApi();
            cfo = new CodeFileObject();
            cfo.FileName = auto.ClsName + "API";
            cfo.FileExt = ".cs";
            cfo.Content = rtbx_api.Text;
            cfos.Add(cfo);

            rtbx_aspx.Text = acoder.CreateAspx();
            cfo = new CodeFileObject();
            cfo.FileName = auto.ClsName + "Manager";
            cfo.FileExt = ".aspx";
            cfo.Content = rtbx_aspx.Text;
            cfos.Add(cfo);

            rtbx_ctrl.Text = acoder.CreateCtrl();
            cfo = new CodeFileObject();
            cfo.FileName = auto.ClsName + "Ctrl";
            cfo.FileExt = ".cs";
            cfo.Content = rtbx_ctrl.Text;
            cfos.Add(cfo);

            rtbx_da.Text = acoder.CreateDA();
            cfo = new CodeFileObject();
            cfo.FileName = auto.ClsName + "DA";
            cfo.FileExt = ".cs";
            cfo.Content = rtbx_da.Text;
            cfos.Add(cfo);

            rtbx_doc.Text = acoder.CreateDoc();
            cfo = new CodeFileObject();
            cfo.FileName = auto.ClsName + "Doc";
            cfo.FileExt = ".txt";
            cfo.Content = rtbx_doc.Text;
            cfos.Add(cfo);

            rtbx_js.Text = acoder.CreateJs();
            cfo = new CodeFileObject();
            cfo.FileName = auto.ClsName + "Manager";
            cfo.FileExt = ".js";
            cfo.Content = rtbx_js.Text;
            cfos.Add(cfo);

            rtbx_lg.Text = acoder.CreateLG();
            cfo = new CodeFileObject();
            cfo.FileName = auto.ClsName + "LG";
            cfo.FileExt = ".cs";
            cfo.Content = rtbx_lg.Text;
            cfos.Add(cfo);

            /*
            rtbx_permit.Text = acoder.CreatePermit();
            cfo = new CodeFileObject();
            cfo.FileName = auto.ClsName + "Permit";
            cfo.FileExt = ".cs";
            cfo.Content = rtbx_permit.Text;
            cfos.Add(cfo); */

            rtbx_qry.Text = acoder.CreateQry();
            cfo = new CodeFileObject();
            cfo.FileName = auto.ClsName + "Qry";
            cfo.FileExt = ".cs";
            cfo.Content = rtbx_qry.Text;
            cfos.Add(cfo);

            rtbx_serv.Text = acoder.CreateServ();
            cfo = new CodeFileObject();
            cfo.FileName = auto.ClsName + "Serv";
            cfo.FileExt = ".cs";
            cfo.Content = rtbx_serv.Text;
            cfos.Add(cfo);

            rtbx_sql.Text = acoder.CreateSQL();
            cfo = new CodeFileObject();
            cfo.FileName = auto.ClsName + "Script";
            cfo.FileExt = ".sql";
            cfo.Content = rtbx_sql.Text;
            cfos.Add(cfo);

            rtbx_view.Text = acoder.CreateView();
            cfo = new CodeFileObject();
            cfo.FileName = auto.ClsName + "View";
            cfo.FileExt = ".aspx";
            cfo.Content = rtbx_view.Text;
            cfos.Add(cfo);

        }
        #endregion

        #region 按钮事件
        private void btn_main_auto_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrWhiteSpace(dbName))
            {
                MessageBox.Show("请选择数据库！", "警告"
                    , MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            //
            int tbIndex = lst_main_tblist.SelectedIndex;
            if (tbIndex >= 0)
            {
                rtbx_info.TextChanged += rtbx_info_TextChanged;

                string tbName = lst_main_tblist.SelectedValue.ToString();
                AutoInitiator ai = new AutoInitiator();

                auto = ai.SetAutoObject(dbName, tbName, SQLTableDict[tbName]);
                //
                DataTable fieldDT = GetMsSqlFiled(tbName);
                if (fieldDT != null && fieldDT.Rows.Count > 0)
                {
                    SetRichTextBox(fieldDT);
                }
                else
                {
                    MessageBox.Show("获取不到表[" + tbName + "]的数据库字段！", "警告"
                    , MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
            }
            else
            {
                MessageBox.Show("请先选择一个表！", "警告"
                    , MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void btn_main_save_Click(object sender, EventArgs e)
        {
            if (cfos != null && cfos.Count > 0)
            {
                string defDir = Environment.CurrentDirectory + "\\CodeFile\\";
                if (!System.IO.Directory.Exists(defDir))
                {
                    System.IO.Directory.CreateDirectory(defDir);
                }
                foreach (CodeFileObject fo in cfos)
                {
                    fo.FilePath = defDir + fo.FileName + fo.FileExt;
                    Run(fo);
                }
            }
            else
            {
                MessageBox.Show("NOT AUTO CREATE CODE!");
            }            
        }

        private void btn_main_reload_Click(object sender, EventArgs e)
        {
            AutoInitiator ai = new AutoInitiator();
            ai.SetEffetive();
            tss_lbl_rtbx_menu.Text = "重新激活配置";
        }

        private void btn_main_config_Click(object sender, EventArgs e)
        {
            FormConfig fc = new FormConfig();
            fc.ShowDialog();
        }

        private void btn_manager_Click(object sender, EventArgs e)
        {
            MessageBox.Show("期待下一版本！");
            //FormManager fm = new FormManager();
            //fm.ShowDialog();
        }

        private void btn_main_template_Click(object sender, EventArgs e)
        {
            FormTemplate ft = new FormTemplate();
            ft.ShowDialog();
        }

        private void btn_main_about_Click(object sender, EventArgs e)
        {
            FormAbout fa = new FormAbout();
            fa.ShowDialog();
            tss_lbl_rtbx_menu.Text = "关于...";
        }
        #endregion

        #region 私用辅助方法

        private void GetMsSqlDBCS()
        {
            dbcs = ConfigurationManager.ConnectionStrings["DBCS"] != null
                ? ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString
                : "";
            //如果配置读取不到，则到SQLite数据库里面读取
            if (string.IsNullOrWhiteSpace(dbcs))
            {
                //从SQLite读取
                ConnBL bl = new ConnBL();
                string connString = "data source={0};initial catalog={1};user id={2};Password={3}";
                DbConnEO conn = bl.GetDbConn("DEFAULT");
                if (conn != null)
                    dbcs = string.Format(connString, conn.DataSource, conn.Catalog, conn.UserId, conn.Password);
            }
            if (string.IsNullOrWhiteSpace(dbcs))
            {
                MessageBox.Show("没有配置master数据库连接字符串！\r\n请配置后重启应用程序！"
                , "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            string[] s = dbcs.Split(';');
            s = s[0].Split('=');
            string dbIpStr = s[1];
            int charIndex = dbIpStr.IndexOf(',');
            string portStr = "";
            if (charIndex >= 0)
            {
                portStr = dbIpStr.Substring(charIndex + 1);
                dbIpStr = dbIpStr.Substring(0, charIndex);
            }
            else
            {
                portStr = "1433";
            }
            //string dbPortStr = charIndex >= 0 ? dbIpStr.Substring(charIndex, 5) : "1433";
            //System.Diagnostics.Debug.WriteLine("portStr=" + portStr);
            int dbPort = int.Parse(portStr);
            int timeOut = 5000; //数据库连接超时时间设置为5秒
            if (NetUtil.IsConnected(dbIpStr, dbPort, timeOut))
            {
                MsSqlHelper.ConnectionString(dbcs); //获取并设置到SQLServer数据库连接字符串
                GetSqlSentence();
            }
            else
            {
                MessageBox.Show("连接不到数据库服务器[" + dbIpStr + ":" + portStr + "]！"
               , "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
                this.Dispose();
            }
        }
        private void GetSqlSentence()
        {
            SentenceBL bl = new SentenceBL();
            List<SQLSentenceEO> sqls = bl.GetSqls();
            if (sqls.Count > 0)
            {
                foreach (SQLSentenceEO sql in sqls)
                {
                    if (!SQLSentenceDict.ContainsKey(sql.SqlName))
                        SQLSentenceDict.Add(sql.SqlName, sql.SqlValue);
                }
            }
            else
            {
                MessageBox.Show("没有配置获取数据库，表，字段的相关语句！\r\n请配置后重启应用程序！"
                    , "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private bool GetMsSqlDatabase()
        {
            try
            {
                string sql = SQLSentenceDict["DBS"];
                DataTable dt = MsSqlHelper.ExecuteDataTable(sql);
                if (dt != null && dt.Rows.Count > 0)
                {
                    cmb_main_dblist.DataSource = dt;
                    cmb_main_dblist.DisplayMember = "name";
                    cmb_main_dblist.ValueMember = "name";
                    cmb_main_dblist.SelectedIndex = 0;

                    return true;
                }
                else
                {
                    MessageBox.Show("找不到用户数据库，请确认数据库连接配置是否正确！"
                        , "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return false;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("连接不到master数据库！\r\n1)请确认数据库连接配置是否正确！\r\n2)请确认SQLServer服务是否已启用！\r\n3)" + ex.Message
                    , "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
                //throw;
            }
        }
        private void GetMsSqlTable(string dbName)
        {
            string tip = "共有用户表{0}个.";

            if (string.IsNullOrWhiteSpace(dbName))
            {
                string msg = "请选择数据库!";
                MessageBox.Show(msg, "警告"
                    , MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            string sql = SQLSentenceDict["TBS"];
            sql = string.Format(sql, dbName);
            DataTable dt = MsSqlHelper.ExecuteDataTable(sql);
            //
            if (dt != null && dt.Rows.Count > 0)
            {
                foreach (DataRow dr in dt.Rows)
                {
                    string name = dr["name"].ToString();
                    string value = dr["value"].ToString();
                    if (!SQLTableDict.ContainsKey(name))
                    {
                        SQLTableDict.Add(name, value);
                    }
                }

                lst_main_tblist.DataSource = dt;
                lst_main_tblist.DisplayMember = "name";
                lst_main_tblist.ValueMember = "name";
                lst_main_tblist.SelectedIndex = -1;
                lbl_tables_tip.Text = string.Format(tip, dt.Rows.Count);
            }
            else
            {
                //dt.Rows.Clear();
                //dt.AcceptChanges();
                lst_main_tblist.DataSource = null;
                lbl_tables_tip.Text = string.Format(tip, 0);
                MessageBox.Show("获取不到当前数据库的用户表！\r\n是否没有创建用户表？"
                    , "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        private DataTable GetMsSqlFiled(string tbName)
        {
            string sql = SQLSentenceDict["FDS"];
            sql = string.Format(sql, tbName, dbName);
            return MsSqlHelper.ExecuteDataTable(sql);
        }

        private void Run(CodeFileObject cfo)
        {
            Thread th = new Thread(new ThreadStart(cfo.WriteFile));
            th.Start();
            //this.tss_lbl_tip.Text = "Save Code File:[" + cfo.FileName + "]";
        }
        
        #endregion

        

    }
}
